package cn.wolfcode.rbac.service.impl;

import cn.wolfcode.rbac.domain.Permission;
import cn.wolfcode.rbac.mapper.PermissionMapper;
import cn.wolfcode.rbac.query.QueryObject;
import cn.wolfcode.rbac.service.IPermissionService;
import cn.wolfcode.rbac.util.RequirePermission;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Service
public class PermissionServiceImpl  implements IPermissionService {
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private ApplicationContext applicationContext;
    @Override
    @Transactional
    public void load() {
        //0.加载所有的表达式List<String>
        List<String> expressions =  permissionMapper.getAllExpressions();
        //1.根据容器对象找到所有@RestController的bean
        Map<String, Object> controllerMap = applicationContext.getBeansWithAnnotation(RestController.class);
        //2.遍历所有Controller的bean,通过反射拿到所有的方法
        Collection<Object> controllers = controllerMap.values();
        for(Object obj:controllers){
            Method[] methods = obj.getClass().getDeclaredMethods();
            //3.获取方法上的@RequirePermission注解
            for(Method method:methods){
                RequirePermission rp = method.getAnnotation(RequirePermission.class);
                if(rp!=null){
                    //4.如果有注解，封装成Permission对象，插入数据库中
                    //5.判断当前方法的表达式是否在List<String>，如果在说明已经有改表达式了，不添加了，否则才条件
                    String expression = rp.expression();
                    if(!expressions.contains(expression)){
                        Permission p = new Permission();
                        p.setName(rp.name());
                        p.setExpression(expression);
                        permissionMapper.insert(p);
                    }
                }
            }
        }


    }

    @Override
    public PageInfo query(QueryObject qo) {
        PageHelper.startPage(qo.getPageNum(),qo.getPageSize());
        List<Permission> permissions = permissionMapper.selectAll();
        return new PageInfo(permissions);
    }

    @Override
    public List<Permission> listAll() {
        return permissionMapper.selectAll();
    }

    @Override
    public List<Permission> queryPermissionByRoleId(Long rid) {
        return permissionMapper.queryPermissionByRoleId(rid);
    }

    @Override
    public List<String> queryPermissionByEId(Long eid) {
        return permissionMapper.queryPermissionByEId(eid);
    }

}
